package org.example.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

/**
 * 反射工具
 *
 * @param <C> 上下文对象
 */
public interface AnnotationUtil<C> {

    /**
     * 初始化反射工具
     *
     * @param context 上下文对象
     * @return 反射工具对象
     */
    AnnotationUtil<C> init(C context) throws Throwable;

    /**
     * 在全局搜索携带指定注解的类对象
     *
     * @param cls 注解类型
     * @return 类名包含此注解的所有类对象集合
     */
    List<Class<?>> getClassByAnnotation(Class<? extends Annotation> cls);

    /**
     * 在指定的类中寻找方法上携带指定注解的所有方法
     *
     * @param oClass 指定的类对象
     * @param mClass 指定的注解的类对象
     * @return 所有携带指定注解的方法的集合
     */
    List<Method> getMethodByAnnotation(Class<?> oClass, Class<? extends Annotation> mClass);

    /**
     * 在指定的类中寻找成员变量上携带指定注解的所有成员变量
     *
     * @param oClass 指定的类对象
     * @param fClass 指定的注解类对象
     * @return 所有携带指定注解的成员变量集合
     */
    List<Field> getFiledByAnnotation(Class<?> oClass, Class<? extends Annotation> fClass);

    /**
     * 在指定的类中寻找方法的参数上携带指定注解的所有参数对象
     *
     * @param oClass 指定的类对象
     * @param pClass 指定的注解类对象
     * @return 所有携带指定注解的参数对象
     */
    List<Parameter> getParameterByAnnotation(Class<?> oClass, Class<? extends Annotation> pClass);

    /**
     * 寻找指定方法中所有携带指定注解的参数
     *
     * @param method 指定的方法对象
     * @param pClass 指定的参数注解类对象
     * @return 携带指定注解的参数对象集合
     */
    List<Parameter> getParameterByAnnotationMethod(Method method, Class<? extends Annotation> pClass);
}
